Full source code website bán hàng thương mại điện tử gần giống shopee
473.339 lượt xem;
1 // Tigra Calendar v5.2 (11/20/2011)
2 // http://www.softcomplex.com/products/tigra_calendar/
3 // License: Public Domain... You're welcome.
4
5 // default settins - this structure can be moved in separate file in multilangual applications
6 var A_TCALCONF = {
7 'cssprefix' : 'tcal',
8 'months' : ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
9 'weekdays' : ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
10 'longwdays' : ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
11 'yearscroll' : true, // show year scroller
12 'weekstart' : 0, // first day of week: 0-Su or 1-Mo
13 'prevyear' : 'Previous Year',
14 'nextyear' : 'Next Year',
15 'prevmonth' : 'Previous Month',
16 'nextmonth' : 'Next Month',
17 'format' : 'd/m/Y' // 'd-m-Y', Y-m-d', 'l, F jS Y'
18 };
19
20 var A_TCALTOKENS = [
21 // A full numeric representation of a year, 4 digits
22 {'t': 'Y', 'r': '19\\d{2}|20\\d{2}', 'p': function (d_date, n_value) { d_date.setFullYear(Number(n_value)); return d_date; }, 'g': function (d_date) { var n_year = d_date.getFullYear(); return n_year; }},
23 // Numeric representation of a month, with leading zeros
24 {'t': 'm', 'r': '0?[1-9]|1[0-2]', 'p': function (d_date, n_value) { d_date.setMonth(Number(n_value) - 1); return d_date; }, 'g': function (d_date) { var n_month = d_date.getMonth() + 1; return (n_month < 10 ? '0' : '') + n_month }},
25 // A full textual representation of a month, such as January or March
26 {'t': 'F', 'r': A_TCALCONF.months.join('|'), 'p': function (d_date, s_value) { for (var m = 0; m < 12; m++) if (A_TCALCONF.months[m] == s_value) { d_date.setMonth(m); return d_date; }}, 'g': function (d_date) { return A_TCALCONF.months[d_date.getMonth()]; }},
27 // Day of the month, 2 digits with leading zeros
28 {'t': 'd', 'r': '0?[1-9]|[12][0-9]|3[01]', 'p': function (d_date, n_value) { d_date.setDate(Number(n_value)); if (d_date.getDate() != n_value) d_date.setDate(0); return d_date }, 'g': function (d_date) { var n_date = d_date.getDate(); return (n_date < 10 ? '0' : '') + n_date; }},
29 // Day of the month without leading zeros
30 {'t': 'j', 'r': '0?[1-9]|[12][0-9]|3[01]', 'p': function (d_date, n_value) { d_date.setDate(Number(n_value)); if (d_date.getDate() != n_value) d_date.setDate(0); return d_date }, 'g': function (d_date) { var n_date = d_date.getDate(); return n_date; }},
31 // A full textual representation of the day of the week
32 {'t': 'l', 'r': A_TCALCONF.longwdays.join('|'), 'p': function (d_date, s_value) { return d_date }, 'g': function (d_date) { return A_TCALCONF.longwdays[d_date.getDay()]; }},
33 // English ordinal suffix for the day of the month, 2 characters
34 {'t': 'S', 'r': 'st|nd|rd|th', 'p': function (d_date, s_value) { return d_date }, 'g': function (d_date) { n_date = d_date.getDate(); if (n_date % 10 == 1 && n_date != 11) return 'st'; if (n_date % 10 == 2 && n_date != 12) return 'nd'; if (n_date % 10 == 3 && n_date != 13) return 'rd'; return 'th'; }}
35
36 ];
37
38 function f_tcalGetHTML (d_date) {
39
40 var e_input = f_tcalGetInputs(true);
41 if (!e_input) return;
42
43 var s_pfx = A_TCALCONF.cssprefix,
44 s_format = A_TCALCONF.format;
45
46 // today from config or client date
47 var d_today = f_tcalParseDate(A_TCALCONF.today, A_TCALCONF.format);
48 if (!d_today)
49 d_today = f_tcalResetTime(new Date());
50
51 // selected date from input or config or today
52 var d_selected = f_tcalParseDate(e_input.value, s_format);
53 if (!d_selected)
54 d_selected = f_tcalParseDate(A_TCALCONF.selected, A_TCALCONF.format);
55 if (!d_selected)
56 d_selected = new Date(d_today);
57
58 // show calendar for passed or selected date
59 d_date = d_date ? f_tcalResetTime(d_date) : new Date(d_selected);
60
61 var d_firstDay = new Date(d_date);
62 d_firstDay.setDate(1);
63 d_firstDay.setDate(1 - (7 + d_firstDay.getDay() - A_TCALCONF.weekstart) % 7);
64
65 var a_class, s_html = '<table id="' + s_pfx + 'Controls"><tbody><tr>'
66 + (A_TCALCONF.yearscroll ? '<td id="' + s_pfx + 'PrevYear" ' + f_tcalRelDate(d_date, -1, 'y') + ' title="' + A_TCALCONF.prevyear + '"></td>' : '')
67 + '<td id="' + s_pfx + 'PrevMonth"' + f_tcalRelDate(d_date, -1) + ' title="' + A_TCALCONF.prevmonth + '"></td><th>'
68 + A_TCALCONF.months[d_date.getMonth()] + ' ' + d_date.getFullYear()
69 + '</th><td id="' + s_pfx + 'NextMonth"' + f_tcalRelDate(d_date, 1) + ' title="' + A_TCALCONF.nextmonth + '"></td>'
70 + (A_TCALCONF.yearscroll ? '<td id="' + s_pfx + 'NextYear"' + f_tcalRelDate(d_date, 1, 'y') + ' title="' + A_TCALCONF.nextyear + '"></td>' : '')
71 + '</tr></tbody></table><table id="' + s_pfx + 'Grid"><tbody><tr>';
72
73 // print weekdays titles
74 for (var i = 0; i < 7; i++)
75 s_html += '<th>' + A_TCALCONF.weekdays[(A_TCALCONF.weekstart + i) % 7] + '</th>';
76 s_html += '</tr>' ;
77
78 // print calendar table
79 var n_date, n_month, d_current = new Date(d_firstDay);
80 while (d_current.getMonth() == d_date.getMonth() ||
81 d_current.getMonth() == d_firstDay.getMonth()) {
82
83 s_html +='<tr>';
84 for (var n_wday = 0; n_wday < 7; n_wday++) {
85
86 a_class = [];
87 n_date = d_current.getDate();
88 n_month = d_current.getMonth();
89
90 if (d_current.getMonth() != d_date.getMonth())
91 a_class[a_class.length] = s_pfx + 'OtherMonth';
92 if (d_current.getDay() == 0 || d_current.getDay() == 6)
93 a_class[a_class.length] = s_pfx + 'Weekend';
94 if (d_current.valueOf() == d_today.valueOf())
95 a_class[a_class.length] = s_pfx + 'Today';
96 if (d_current.valueOf() == d_selected.valueOf())
97 a_class[a_class.length] = s_pfx + 'Selected';
98
99 s_html += '<td' + f_tcalRelDate(d_current) + (a_class.length ? ' class="' + a_class.join(' ') + '">' : '>') + n_date + '</td>';
100 d_current.setDate(++n_date);
101 }
102 s_html +='</tr>';
103 }
104 s_html +='</tbody></table>';
105
106 return s_html;
107 }
108
109 function f_tcalRelDate (d_date, d_diff, s_units) {
110
111 var s_units = (s_units == 'y' ? 'FullYear' : 'Month');
112 var d_result = new Date(d_date);
113 if (d_diff) {
114 d_result['set' + s_units](d_date['get' + s_units]() + d_diff);
115 if (d_result.getDate() != d_date.getDate())
116 d_result.setDate(0);
117 }
118 return ' onclick="f_tcalUpdate(' + d_result.valueOf() + (d_diff ? ',1' : '') + ')"';
119 }
120
121 function f_tcalResetTime (d_date) {
122 d_date.setMilliseconds(0);
123 d_date.setSeconds(0);
124 d_date.setMinutes(0);
125 d_date.setHours(12);
126 return d_date;
127 }
128
129 // closes calendar and returns all inputs to default state
130 function f_tcalCancel () {
131
132 var s_pfx = A_TCALCONF.cssprefix;
133 var e_cal = document.getElementById(s_pfx);
134 if (e_cal)
135 e_cal.style.visibility = '';
136 var a_inputs = f_tcalGetInputs();
137 for (var n = 0; n < a_inputs.length; n++)
138 f_tcalRemoveClass(a_inputs[n], s_pfx + 'Active');
139 }
140
141 function f_tcalUpdate (n_date, b_keepOpen) {
142
143 var e_input = f_tcalGetInputs(true);
144 if (!e_input) return;
145
146 d_date = new Date(n_date);
147 var s_pfx = A_TCALCONF.cssprefix;
148
149 if (b_keepOpen) {
150 var e_cal = document.getElementById(s_pfx);
151 if (!e_cal || e_cal.style.visibility != 'visible') return;
152 e_cal.innerHTML = f_tcalGetHTML(d_date, e_input);
153 }
154 else {
155 e_input.value = f_tcalGenerateDate(d_date, A_TCALCONF.format);
156 f_tcalCancel();
157 }
158 }
159
160 function f_tcalOnClick () {
161
162 // see if already opened
163 var s_pfx = A_TCALCONF.cssprefix;
164 var s_activeClass = s_pfx + 'Active';
165 var b_close = f_tcalHasClass(this, s_activeClass);
166
167 // close all clalendars
168 f_tcalCancel();
169 if (b_close) return;
170
171 // get position of input
172 f_tcalAddClass(this, s_activeClass);
173
174 var n_left = f_getPosition (this, 'Left'),
175 n_top = f_getPosition (this, 'Top') + this.offsetHeight;
176
177 var e_cal = document.getElementById(s_pfx);
178 if (!e_cal) {
179 e_cal = document.createElement('div');
180 e_cal.onselectstart = function () { return false };
181 e_cal.id = s_pfx;
182 document.getElementsByTagName("body").item(0).appendChild(e_cal);
183 }
184 e_cal.innerHTML = f_tcalGetHTML(null);
185 e_cal.style.top = n_top + 'px';
186 e_cal.style.left = (n_left + this.offsetWidth - e_cal.offsetWidth) + 'px';
187 e_cal.style.visibility = 'visible';
188 }
189
190 function f_tcalParseDate (s_date, s_format) {
191
192 if (!s_date) return;
193
194 var s_char, s_regexp = '^', a_tokens = {}, a_options, n_token = 0;
195 for (var n = 0; n < s_format.length; n++) {
196 s_char = s_format.charAt(n);
197 if (A_TCALTOKENS_IDX[s_char]) {
198 a_tokens[s_char] = ++n_token;
199 s_regexp += '(' + A_TCALTOKENS_IDX[s_char]['r'] + ')';
200 }
201 else if (s_char == ' ')
202 s_regexp += '\\s';
203 else
204 s_regexp += (s_char.match(/[\w\d]/) ? '' : '\\') + s_char;
205 }
206 var r_date = new RegExp(s_regexp + '$');
207 if (!s_date.match(r_date)) return;
208
209 var s_val, d_date = f_tcalResetTime(new Date());
210 d_date.setDate(1);
211
212 for (n = 0; n < A_TCALTOKENS.length; n++) {
213 s_char = A_TCALTOKENS[n]['t'];
214 if (!a_tokens[s_char])
215 continue;
216 s_val = RegExp['$' + a_tokens[s_char]];
217 d_date = A_TCALTOKENS[n]['p'](d_date, s_val);
218 }
219
220 return d_date;
221 }
222
223 function f_tcalGenerateDate (d_date, s_format) {
224
225 var s_char, s_date = '';
226 for (var n = 0; n < s_format.length; n++) {
227 s_char = s_format.charAt(n);
228 s_date += A_TCALTOKENS_IDX[s_char] ? A_TCALTOKENS_IDX[s_char]['g'](d_date) : s_char;
229 }
230 return s_date;
231 }
232
233 function f_tcalGetInputs (b_active) {
234
235 var a_inputs = document.getElementsByTagName('input'),
236 e_input, s_rel, a_result = [];
237
238 for (n = 0; n < a_inputs.length; n++) {
239
240 e_input = a_inputs[n];
241 if (!e_input.type || e_input.type != 'text')
242 continue;
243
244 if (!f_tcalHasClass(e_input, 'tcal'))
245 continue;
246
247 if (b_active && f_tcalHasClass(e_input, A_TCALCONF.cssprefix + 'Active'))
248 return e_input;
249
250 a_result[a_result.length] = e_input;
251 }
252 return b_active ? null : a_result;
253 }
254
255 function f_tcalHasClass (e_elem, s_class) {
256 var s_classes = e_elem.className;
257 if (!s_classes)
258 return false;
259 var a_classes = s_classes.split(' ');
260 for (var n = 0; n < a_classes.length; n++)
261 if (a_classes[n] == s_class)
262 return true;
263 return false;
264 }
265
266 function f_tcalAddClass (e_elem, s_class) {
267 if (f_tcalHasClass (e_elem, s_class))
268 return;
269
270 var s_classes = e_elem.className;
271 e_elem.className = (s_classes ? s_classes + ' ' : '') + s_class;
272 }
273
274 function f_tcalRemoveClass (e_elem, s_class) {
275 var s_classes = e_elem.className;
276 if (!s_classes || s_classes.indexOf(s_class) == -1)
277 return false;
278
279 var a_classes = s_classes.split(' '),
280 a_newClasses = [];
281
282 for (var n = 0; n < a_classes.length; n++) {
283 if (a_classes[n] == s_class)
284 continue;
285 a_newClasses[a_newClasses.length] = a_classes[n];
286 }
287 e_elem.className = a_newClasses.join(' ');
288 return true;
289 }
290
291 function f_getPosition (e_elemRef, s_coord) {
292 var n_pos = 0, n_offset,
293 e_elem = e_elemRef;
294
295 while (e_elem) {
296 n_offset = e_elem["offset" + s_coord];
297 n_pos += n_offset;
298 e_elem = e_elem.offsetParent;
299 }
300
301 e_elem = e_elemRef;
302 while (e_elem != document.body) {
303 n_offset = e_elem["scroll" + s_coord];
304 if (n_offset && e_elem.style.overflow == 'scroll')
305 n_pos -= n_offset;
306 e_elem = e_elem.parentNode;
307 }
308 return n_pos;
309 }
310
311 function f_tcalInit () {
312
313 if (!document.getElementsByTagName)
314 return;
315
316 var e_input, a_inputs = f_tcalGetInputs();
317 for (var n = 0; n < a_inputs.length; n++) {
318 e_input = a_inputs[n];
319 e_input.onclick = f_tcalOnClick;
320 f_tcalAddClass(e_input, A_TCALCONF.cssprefix + 'Input');
321 }
322
323 window.A_TCALTOKENS_IDX = {};
324 for (n = 0; n < A_TCALTOKENS.length; n++)
325 A_TCALTOKENS_IDX[A_TCALTOKENS[n]['t']] = A_TCALTOKENS[n];
326 }
327
328 function f_tcalAddOnload (f_func) {
329 if (document.addEventListener) {
330 window.addEventListener('load', f_func, false);
331 }
332 else if (window.attachEvent) {
333 window.attachEvent('onload', f_func);
334 }
335 else {
336 var f_onLoad = window.onload;
337 if (typeof window.onload != 'function') {
338 window.onload = f_func;
339 }
340 else {
341 window.onload = function() {
342 f_onLoad();
343 f_func();
344 }
345 }
346 }
347 }
348
349 f_tcalAddOnload (f_tcalInit);
2 // http://www.softcomplex.com/products/tigra_calendar/
3 // License: Public Domain... You're welcome.
4
5 // default settins - this structure can be moved in separate file in multilangual applications
6 var A_TCALCONF = {
7 'cssprefix' : 'tcal',
8 'months' : ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
9 'weekdays' : ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
10 'longwdays' : ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
11 'yearscroll' : true, // show year scroller
12 'weekstart' : 0, // first day of week: 0-Su or 1-Mo
13 'prevyear' : 'Previous Year',
14 'nextyear' : 'Next Year',
15 'prevmonth' : 'Previous Month',
16 'nextmonth' : 'Next Month',
17 'format' : 'd/m/Y' // 'd-m-Y', Y-m-d', 'l, F jS Y'
18 };
19
20 var A_TCALTOKENS = [
21 // A full numeric representation of a year, 4 digits
22 {'t': 'Y', 'r': '19\\d{2}|20\\d{2}', 'p': function (d_date, n_value) { d_date.setFullYear(Number(n_value)); return d_date; }, 'g': function (d_date) { var n_year = d_date.getFullYear(); return n_year; }},
23 // Numeric representation of a month, with leading zeros
24 {'t': 'm', 'r': '0?[1-9]|1[0-2]', 'p': function (d_date, n_value) { d_date.setMonth(Number(n_value) - 1); return d_date; }, 'g': function (d_date) { var n_month = d_date.getMonth() + 1; return (n_month < 10 ? '0' : '') + n_month }},
25 // A full textual representation of a month, such as January or March
26 {'t': 'F', 'r': A_TCALCONF.months.join('|'), 'p': function (d_date, s_value) { for (var m = 0; m < 12; m++) if (A_TCALCONF.months[m] == s_value) { d_date.setMonth(m); return d_date; }}, 'g': function (d_date) { return A_TCALCONF.months[d_date.getMonth()]; }},
27 // Day of the month, 2 digits with leading zeros
28 {'t': 'd', 'r': '0?[1-9]|[12][0-9]|3[01]', 'p': function (d_date, n_value) { d_date.setDate(Number(n_value)); if (d_date.getDate() != n_value) d_date.setDate(0); return d_date }, 'g': function (d_date) { var n_date = d_date.getDate(); return (n_date < 10 ? '0' : '') + n_date; }},
29 // Day of the month without leading zeros
30 {'t': 'j', 'r': '0?[1-9]|[12][0-9]|3[01]', 'p': function (d_date, n_value) { d_date.setDate(Number(n_value)); if (d_date.getDate() != n_value) d_date.setDate(0); return d_date }, 'g': function (d_date) { var n_date = d_date.getDate(); return n_date; }},
31 // A full textual representation of the day of the week
32 {'t': 'l', 'r': A_TCALCONF.longwdays.join('|'), 'p': function (d_date, s_value) { return d_date }, 'g': function (d_date) { return A_TCALCONF.longwdays[d_date.getDay()]; }},
33 // English ordinal suffix for the day of the month, 2 characters
34 {'t': 'S', 'r': 'st|nd|rd|th', 'p': function (d_date, s_value) { return d_date }, 'g': function (d_date) { n_date = d_date.getDate(); if (n_date % 10 == 1 && n_date != 11) return 'st'; if (n_date % 10 == 2 && n_date != 12) return 'nd'; if (n_date % 10 == 3 && n_date != 13) return 'rd'; return 'th'; }}
35
36 ];
37
38 function f_tcalGetHTML (d_date) {
39
40 var e_input = f_tcalGetInputs(true);
41 if (!e_input) return;
42
43 var s_pfx = A_TCALCONF.cssprefix,
44 s_format = A_TCALCONF.format;
45
46 // today from config or client date
47 var d_today = f_tcalParseDate(A_TCALCONF.today, A_TCALCONF.format);
48 if (!d_today)
49 d_today = f_tcalResetTime(new Date());
50
51 // selected date from input or config or today
52 var d_selected = f_tcalParseDate(e_input.value, s_format);
53 if (!d_selected)
54 d_selected = f_tcalParseDate(A_TCALCONF.selected, A_TCALCONF.format);
55 if (!d_selected)
56 d_selected = new Date(d_today);
57
58 // show calendar for passed or selected date
59 d_date = d_date ? f_tcalResetTime(d_date) : new Date(d_selected);
60
61 var d_firstDay = new Date(d_date);
62 d_firstDay.setDate(1);
63 d_firstDay.setDate(1 - (7 + d_firstDay.getDay() - A_TCALCONF.weekstart) % 7);
64
65 var a_class, s_html = '<table id="' + s_pfx + 'Controls"><tbody><tr>'
66 + (A_TCALCONF.yearscroll ? '<td id="' + s_pfx + 'PrevYear" ' + f_tcalRelDate(d_date, -1, 'y') + ' title="' + A_TCALCONF.prevyear + '"></td>' : '')
67 + '<td id="' + s_pfx + 'PrevMonth"' + f_tcalRelDate(d_date, -1) + ' title="' + A_TCALCONF.prevmonth + '"></td><th>'
68 + A_TCALCONF.months[d_date.getMonth()] + ' ' + d_date.getFullYear()
69 + '</th><td id="' + s_pfx + 'NextMonth"' + f_tcalRelDate(d_date, 1) + ' title="' + A_TCALCONF.nextmonth + '"></td>'
70 + (A_TCALCONF.yearscroll ? '<td id="' + s_pfx + 'NextYear"' + f_tcalRelDate(d_date, 1, 'y') + ' title="' + A_TCALCONF.nextyear + '"></td>' : '')
71 + '</tr></tbody></table><table id="' + s_pfx + 'Grid"><tbody><tr>';
72
73 // print weekdays titles
74 for (var i = 0; i < 7; i++)
75 s_html += '<th>' + A_TCALCONF.weekdays[(A_TCALCONF.weekstart + i) % 7] + '</th>';
76 s_html += '</tr>' ;
77
78 // print calendar table
79 var n_date, n_month, d_current = new Date(d_firstDay);
80 while (d_current.getMonth() == d_date.getMonth() ||
81 d_current.getMonth() == d_firstDay.getMonth()) {
82
83 s_html +='<tr>';
84 for (var n_wday = 0; n_wday < 7; n_wday++) {
85
86 a_class = [];
87 n_date = d_current.getDate();
88 n_month = d_current.getMonth();
89
90 if (d_current.getMonth() != d_date.getMonth())
91 a_class[a_class.length] = s_pfx + 'OtherMonth';
92 if (d_current.getDay() == 0 || d_current.getDay() == 6)
93 a_class[a_class.length] = s_pfx + 'Weekend';
94 if (d_current.valueOf() == d_today.valueOf())
95 a_class[a_class.length] = s_pfx + 'Today';
96 if (d_current.valueOf() == d_selected.valueOf())
97 a_class[a_class.length] = s_pfx + 'Selected';
98
99 s_html += '<td' + f_tcalRelDate(d_current) + (a_class.length ? ' class="' + a_class.join(' ') + '">' : '>') + n_date + '</td>';
100 d_current.setDate(++n_date);
101 }
102 s_html +='</tr>';
103 }
104 s_html +='</tbody></table>';
105
106 return s_html;
107 }
108
109 function f_tcalRelDate (d_date, d_diff, s_units) {
110
111 var s_units = (s_units == 'y' ? 'FullYear' : 'Month');
112 var d_result = new Date(d_date);
113 if (d_diff) {
114 d_result['set' + s_units](d_date['get' + s_units]() + d_diff);
115 if (d_result.getDate() != d_date.getDate())
116 d_result.setDate(0);
117 }
118 return ' onclick="f_tcalUpdate(' + d_result.valueOf() + (d_diff ? ',1' : '') + ')"';
119 }
120
121 function f_tcalResetTime (d_date) {
122 d_date.setMilliseconds(0);
123 d_date.setSeconds(0);
124 d_date.setMinutes(0);
125 d_date.setHours(12);
126 return d_date;
127 }
128
129 // closes calendar and returns all inputs to default state
130 function f_tcalCancel () {
131
132 var s_pfx = A_TCALCONF.cssprefix;
133 var e_cal = document.getElementById(s_pfx);
134 if (e_cal)
135 e_cal.style.visibility = '';
136 var a_inputs = f_tcalGetInputs();
137 for (var n = 0; n < a_inputs.length; n++)
138 f_tcalRemoveClass(a_inputs[n], s_pfx + 'Active');
139 }
140
141 function f_tcalUpdate (n_date, b_keepOpen) {
142
143 var e_input = f_tcalGetInputs(true);
144 if (!e_input) return;
145
146 d_date = new Date(n_date);
147 var s_pfx = A_TCALCONF.cssprefix;
148
149 if (b_keepOpen) {
150 var e_cal = document.getElementById(s_pfx);
151 if (!e_cal || e_cal.style.visibility != 'visible') return;
152 e_cal.innerHTML = f_tcalGetHTML(d_date, e_input);
153 }
154 else {
155 e_input.value = f_tcalGenerateDate(d_date, A_TCALCONF.format);
156 f_tcalCancel();
157 }
158 }
159
160 function f_tcalOnClick () {
161
162 // see if already opened
163 var s_pfx = A_TCALCONF.cssprefix;
164 var s_activeClass = s_pfx + 'Active';
165 var b_close = f_tcalHasClass(this, s_activeClass);
166
167 // close all clalendars
168 f_tcalCancel();
169 if (b_close) return;
170
171 // get position of input
172 f_tcalAddClass(this, s_activeClass);
173
174 var n_left = f_getPosition (this, 'Left'),
175 n_top = f_getPosition (this, 'Top') + this.offsetHeight;
176
177 var e_cal = document.getElementById(s_pfx);
178 if (!e_cal) {
179 e_cal = document.createElement('div');
180 e_cal.onselectstart = function () { return false };
181 e_cal.id = s_pfx;
182 document.getElementsByTagName("body").item(0).appendChild(e_cal);
183 }
184 e_cal.innerHTML = f_tcalGetHTML(null);
185 e_cal.style.top = n_top + 'px';
186 e_cal.style.left = (n_left + this.offsetWidth - e_cal.offsetWidth) + 'px';
187 e_cal.style.visibility = 'visible';
188 }
189
190 function f_tcalParseDate (s_date, s_format) {
191
192 if (!s_date) return;
193
194 var s_char, s_regexp = '^', a_tokens = {}, a_options, n_token = 0;
195 for (var n = 0; n < s_format.length; n++) {
196 s_char = s_format.charAt(n);
197 if (A_TCALTOKENS_IDX[s_char]) {
198 a_tokens[s_char] = ++n_token;
199 s_regexp += '(' + A_TCALTOKENS_IDX[s_char]['r'] + ')';
200 }
201 else if (s_char == ' ')
202 s_regexp += '\\s';
203 else
204 s_regexp += (s_char.match(/[\w\d]/) ? '' : '\\') + s_char;
205 }
206 var r_date = new RegExp(s_regexp + '$');
207 if (!s_date.match(r_date)) return;
208
209 var s_val, d_date = f_tcalResetTime(new Date());
210 d_date.setDate(1);
211
212 for (n = 0; n < A_TCALTOKENS.length; n++) {
213 s_char = A_TCALTOKENS[n]['t'];
214 if (!a_tokens[s_char])
215 continue;
216 s_val = RegExp['$' + a_tokens[s_char]];
217 d_date = A_TCALTOKENS[n]['p'](d_date, s_val);
218 }
219
220 return d_date;
221 }
222
223 function f_tcalGenerateDate (d_date, s_format) {
224
225 var s_char, s_date = '';
226 for (var n = 0; n < s_format.length; n++) {
227 s_char = s_format.charAt(n);
228 s_date += A_TCALTOKENS_IDX[s_char] ? A_TCALTOKENS_IDX[s_char]['g'](d_date) : s_char;
229 }
230 return s_date;
231 }
232
233 function f_tcalGetInputs (b_active) {
234
235 var a_inputs = document.getElementsByTagName('input'),
236 e_input, s_rel, a_result = [];
237
238 for (n = 0; n < a_inputs.length; n++) {
239
240 e_input = a_inputs[n];
241 if (!e_input.type || e_input.type != 'text')
242 continue;
243
244 if (!f_tcalHasClass(e_input, 'tcal'))
245 continue;
246
247 if (b_active && f_tcalHasClass(e_input, A_TCALCONF.cssprefix + 'Active'))
248 return e_input;
249
250 a_result[a_result.length] = e_input;
251 }
252 return b_active ? null : a_result;
253 }
254
255 function f_tcalHasClass (e_elem, s_class) {
256 var s_classes = e_elem.className;
257 if (!s_classes)
258 return false;
259 var a_classes = s_classes.split(' ');
260 for (var n = 0; n < a_classes.length; n++)
261 if (a_classes[n] == s_class)
262 return true;
263 return false;
264 }
265
266 function f_tcalAddClass (e_elem, s_class) {
267 if (f_tcalHasClass (e_elem, s_class))
268 return;
269
270 var s_classes = e_elem.className;
271 e_elem.className = (s_classes ? s_classes + ' ' : '') + s_class;
272 }
273
274 function f_tcalRemoveClass (e_elem, s_class) {
275 var s_classes = e_elem.className;
276 if (!s_classes || s_classes.indexOf(s_class) == -1)
277 return false;
278
279 var a_classes = s_classes.split(' '),
280 a_newClasses = [];
281
282 for (var n = 0; n < a_classes.length; n++) {
283 if (a_classes[n] == s_class)
284 continue;
285 a_newClasses[a_newClasses.length] = a_classes[n];
286 }
287 e_elem.className = a_newClasses.join(' ');
288 return true;
289 }
290
291 function f_getPosition (e_elemRef, s_coord) {
292 var n_pos = 0, n_offset,
293 e_elem = e_elemRef;
294
295 while (e_elem) {
296 n_offset = e_elem["offset" + s_coord];
297 n_pos += n_offset;
298 e_elem = e_elem.offsetParent;
299 }
300
301 e_elem = e_elemRef;
302 while (e_elem != document.body) {
303 n_offset = e_elem["scroll" + s_coord];
304 if (n_offset && e_elem.style.overflow == 'scroll')
305 n_pos -= n_offset;
306 e_elem = e_elem.parentNode;
307 }
308 return n_pos;
309 }
310
311 function f_tcalInit () {
312
313 if (!document.getElementsByTagName)
314 return;
315
316 var e_input, a_inputs = f_tcalGetInputs();
317 for (var n = 0; n < a_inputs.length; n++) {
318 e_input = a_inputs[n];
319 e_input.onclick = f_tcalOnClick;
320 f_tcalAddClass(e_input, A_TCALCONF.cssprefix + 'Input');
321 }
322
323 window.A_TCALTOKENS_IDX = {};
324 for (n = 0; n < A_TCALTOKENS.length; n++)
325 A_TCALTOKENS_IDX[A_TCALTOKENS[n]['t']] = A_TCALTOKENS[n];
326 }
327
328 function f_tcalAddOnload (f_func) {
329 if (document.addEventListener) {
330 window.addEventListener('load', f_func, false);
331 }
332 else if (window.attachEvent) {
333 window.attachEvent('onload', f_func);
334 }
335 else {
336 var f_onLoad = window.onload;
337 if (typeof window.onload != 'function') {
338 window.onload = f_func;
339 }
340 else {
341 window.onload = function() {
342 f_onLoad();
343 f_func();
344 }
345 }
346 }
347 }
348
349 f_tcalAddOnload (f_tcalInit);